package com.nanhai.buddhist.college.module.collegebase.service.accommodationreside;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nanhai.buddhist.college.framework.common.pojo.PageResult;
import com.nanhai.buddhist.college.framework.common.util.collection.CollectionUtils;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.accommodationreside.vo.AccommodationResideCreateReqVO;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.accommodationreside.vo.AccommodationResideExportReqVO;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.accommodationreside.vo.AccommodationResidePageReqVO;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.accommodationreside.vo.AccommodationResideUpdateReqVO;
import com.nanhai.buddhist.college.module.collegebase.convert.accommodationreside.AccommodationResideConvert;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.accommodationbed.AccommodationBedDO;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.accommodationreside.AccommodationResideDO;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.accommodationroom.AccommodationRoomDO;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.studentroll.StudentRollDO;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.teacherteachers.TeacherTeachersDO;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.accommodationbed.AccommodationBedMapper;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.accommodationreside.AccommodationResideMapper;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.accommodationroom.AccommodationRoomMapper;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.studentroll.StudentRollMapper;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.teacherteachers.TeacherTeachersMapper;
import com.nanhai.buddhist.college.module.collegebase.enums.AccommodationRoomTypeEnum;
import com.nanhai.buddhist.college.module.collegebase.enums.BooleanIntEnum;
import com.nanhai.buddhist.college.module.collegebase.enums.ErrorCodeConstants;
import com.nanhai.buddhist.college.module.collegebase.enums.ResideStatusEnum;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import static com.nanhai.buddhist.college.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.nanhai.buddhist.college.module.collegebase.enums.ErrorCodeConstants.ACCOMMODATION_RESIDE_NOT_EXISTS;

/**
 * 入住记录 Service 实现类
 *
 * @author 南海佛学院
 */
@Service
@Validated
public class AccommodationResideServiceImpl implements AccommodationResideService {

    @Resource
    private AccommodationResideMapper accommodationResideMapper;

    @Resource
    private AccommodationRoomMapper accommodationRoomMapper;

    @Resource
    private AccommodationBedMapper accommodationBedMapper;
    @Resource
    private StudentRollMapper studentRollMapper;
    @Resource
    private TeacherTeachersMapper teacherTeachersMapper;


    @Override
    @Transactional
    public String createAccommodationReside(AccommodationResideCreateReqVO createReqVO) {
        LambdaQueryWrapper<AccommodationResideDO> checkWrapper = new LambdaQueryWrapper<>();
        checkWrapper.eq(AccommodationResideDO::getResideId, createReqVO.getResideId())
                .eq(AccommodationResideDO::getRole, createReqVO.getRole())
                .eq(AccommodationResideDO::getResideStatus, ResideStatusEnum.RESIDE.getStatus());

        Long selectCount = accommodationResideMapper.selectCount(checkWrapper);
        if (ObjectUtil.isNotNull(selectCount) && selectCount > 0) {
            throw exception(ErrorCodeConstants.HAVE_RESIDE_ERROR);
        }

        // 插入
        AccommodationResideDO accommodationReside = AccommodationResideConvert.INSTANCE.convert(createReqVO);
        accommodationReside.setResideStatus(ResideStatusEnum.RESIDE.getStatus());
        accommodationResideMapper.insert(accommodationReside);
        setOccupy(createReqVO);
        // 有迁出记录删除
        deletedReside(createReqVO.getResideId(),createReqVO.getRole() );
        // 返回
        return accommodationReside.getId();
    }

    private void setOccupy(AccommodationResideCreateReqVO createReqVO) {
        AccommodationBedDO accommodationBedDO = accommodationBedMapper.selectById(createReqVO.getBedId());
        accommodationBedDO.setOccupy(BooleanIntEnum.TRUE.getStatus());
        accommodationBedMapper.updateById(accommodationBedDO);
    }

    @Override
    public void updateAccommodationReside(AccommodationResideUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateAccommodationResideExists(updateReqVO.getId());
        // 更新
        AccommodationResideDO updateObj = AccommodationResideConvert.INSTANCE.convert(updateReqVO);
        accommodationResideMapper.updateById(updateObj);
    }

    @Override
    public void deleteAccommodationReside(String id) {
        // 校验存在
        this.validateAccommodationResideExists(id);
        // 删除
        accommodationResideMapper.deleteById(id);
    }

    private void validateAccommodationResideExists(String id) {
        if (accommodationResideMapper.selectById(id) == null) {
            throw exception(ACCOMMODATION_RESIDE_NOT_EXISTS);
        }
    }

    @Override
    public AccommodationResideDO getAccommodationReside(String id) {
        AccommodationResideDO accommodationResideDO = accommodationResideMapper.selectById(id);
        AccommodationBedDO accommodationBedDO = accommodationBedMapper.selectById(accommodationResideDO.getBedId());
        if (ObjectUtil.isNotNull(accommodationBedDO)) {
            AccommodationRoomDO accommodationRoomDO = accommodationRoomMapper.selectById(accommodationBedDO.getRoomId());
            accommodationResideDO.setDepartmentId(accommodationRoomDO.getDepartmentId());
            accommodationResideDO.setRoomId(accommodationRoomDO.getId());
        }
        return accommodationResideDO;
    }

    @Override
    public List<AccommodationResideDO> getAccommodationResideList(Collection<String> ids) {
        return CollectionUtils.isEmpty(ids) ? Collections.emptyList() : accommodationResideMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<AccommodationResideDO> getAccommodationResidePage(AccommodationResidePageReqVO pageReqVO) {
        PageResult<AccommodationResideDO> page = accommodationResideMapper.selectPage(pageReqVO);
        List<AccommodationResideDO> list = page.getList();


        list.forEach(item -> {
            if (AccommodationRoomTypeEnum.STUDENT.getType().equals(item.getRole())) {
                StudentRollDO studentRollDO = studentRollMapper.selectById(item.getResideId());
                if (ObjectUtil.isNotNull(studentRollDO)) {
                    item.setResidePhone(studentRollDO.getPhone());
                }
            } else if (AccommodationRoomTypeEnum.TEACHER.getType().equals(item.getRole())) {
                TeacherTeachersDO aDo = teacherTeachersMapper.selectById(item.getResideId());
                if (ObjectUtil.isNotNull(aDo)) {
                    item.setResidePhone(aDo.getTeacherTelephone());
                }
            } else {
                // todo  等待职工信息完善
            }
        });
        page.setList(list);
        return page;
    }

    @Override
    public List<AccommodationResideDO> getAccommodationResideList(AccommodationResideExportReqVO exportReqVO) {
        return accommodationResideMapper.selectList(exportReqVO);
    }

    @Override
    @Transactional
    public void updateAccommodationStatusReside(String id) {
        // 修改转态迁出
        AccommodationResideDO resideDO = accommodationResideMapper.selectById(id);
        if (resideDO.getResideStatus().equals(ResideStatusEnum.OUT.getStatus())) {
            throw exception(ErrorCodeConstants.CLIENT_ERROR);
        }

        resideDO.setResideStatus(ResideStatusEnum.OUT.getStatus());
        accommodationResideMapper.updateById(resideDO);

        // 修改床铺状态
        AccommodationBedDO accommodationBedDO = accommodationBedMapper.selectById(resideDO.getBedId());
        if (ObjectUtil.isNull(accommodationBedDO)) {
            return;
        }
        accommodationBedDO.setOccupy(BooleanIntEnum.FALSE.getStatus());
        accommodationBedMapper.updateById(accommodationBedDO);
    }

    @Override
    @Transactional
    public String addAccommodationReside(AccommodationResideCreateReqVO createReqVO) { // 插入
        AccommodationResideDO accommodationReside = AccommodationResideConvert.INSTANCE.convert(createReqVO);
        accommodationReside.setResideStatus(ResideStatusEnum.RESIDE.getStatus());
        accommodationResideMapper.insert(accommodationReside);
        setOccupy(createReqVO);

        deletedReside(createReqVO.getResideId(),createReqVO.getRole() );
        // 返回
        return accommodationReside.getId();
    }

    private void deletedReside(String resideId, Integer role) {
        AccommodationResideDO resideDO = accommodationResideMapper.selectOne(new LambdaQueryWrapper<AccommodationResideDO>()
                .eq(AccommodationResideDO::getResideId, resideId)
                .eq(AccommodationResideDO::getRole, role)
                .eq(AccommodationResideDO::getResideStatus, ResideStatusEnum.OUT.getStatus())
                .last("limit 1"));

        if (ObjectUtil.isNotNull(resideDO)) {
            accommodationResideMapper.deleteById(resideDO);
        }
    }

}
